package com.athui.bean.task;

import com.athui.bean.config.ConnectInfo;
import com.athui.bean.metadata.TableMetaData;
import com.athui.utils.explorer.metadata.JdbcExplorer;
import com.athui.utils.explorer.metadata.MetaDataExplorer;
import com.athui.utils.explorer.strategy.ExplorerStrategy;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @description: TODO
 * @autor: zhangzhonghui
 * @create: 2024-08-29 07:16
 * @Version: 1.0
 */
public class JdbcTask extends SameTask implements Serializable{


    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");


    private Map<String,String> tableMap;

    /**
     * @description: TODO 扫描策略
     * @author: 阿辉大人
     * @create: 2024/8/29 06:57
     * @version: 1.0
     **/
    private String scanStrategy = ExplorerStrategy.FULL_SCAN_STRATEGY;

    /**
     * @description: TODO 任务ID
     * @author: 阿辉大人
     * @create: 2024/8/3 14:57
     * @version: 1.0
     **/
    private Long taskCode = System.currentTimeMillis();

    /**
     * @description: TODO 连接配置
     * @author: 阿辉大人
     * @create: 2024/8/3 14:58
     * @version: 1.0
     **/
    private ConnectInfo connectInfo;
    /**
     * @description: TODO 元数据探查器
     * @author: 阿辉大人
     * @create: 2024/8/3 14:58
     * @version: 1.0
     **/
    private transient MetaDataExplorer metaDataExplorer;
    /**
     * @description: TODO 探查策略
     * @author: 阿辉大人
     * @create: 2024/8/3 14:59
     * @version: 1.0
     **/
    private transient ExplorerStrategy explorerStrategy;

    /**
     * @description: TODO 行数限制
     * 默认为一百万，配置 -1 将不受限制
     * @author: 阿辉大人
     * @create: 2024/8/3 15:00
     * @version: 1.0
     **/
    private Integer rowSizeLimit = 100_0000;

    /**
     * @description: TODO 每个批次执行大小
     * 默认为 100，可根据实际情况进行调整
     * @author: 阿辉大人
     * @create: 2024/8/3 15:03
     * @version: 1.0
     **/
    private Integer fetchSize = 100;

    public JdbcTask(Map<String,String> tableMap,
                    ConnectInfo connectInfo,
                    MetaDataExplorer metaDataExplorer,
                    ExplorerStrategy explorerStrategy) {

        this.tableMap = tableMap;

        this.connectInfo = connectInfo;
        this.metaDataExplorer = metaDataExplorer;
        this.explorerStrategy = explorerStrategy;

    }

    public JdbcTask(
            String databaseName,
            String tableName,
            ConnectInfo connectInfo,
            JdbcExplorer jdbcExplorer,
            ExplorerStrategy explorerStrategy) {
        this(new HashMap<>(), connectInfo, jdbcExplorer, explorerStrategy);
        tableMap.put(tableName,databaseName);
    }

    public int getTableCount(){
        return tableMap.keySet().size();
    }


    public Long getTaskCode() { return taskCode; }

    public String getEndTime() {
        return DATE_TIME_FORMATTER.format(LocalDateTime.now());
    }


    public ConnectInfo getConnectInfo() {
        return connectInfo;
    }

    public void setConnectInfo(ConnectInfo connectInfo) {
        this.connectInfo = connectInfo;
    }

    public MetaDataExplorer getMetaDataExplorer() {
        return metaDataExplorer;
    }

    public void setMetaDataExplorer(MetaDataExplorer metaDataExplorer) {
        this.metaDataExplorer = metaDataExplorer;
    }

    public ExplorerStrategy getExplorerStrategy() {
        return explorerStrategy;
    }

    public void setExplorerStrategy(ExplorerStrategy explorerStrategy) {
        this.explorerStrategy = explorerStrategy;
    }

    public Integer getRowSizeLimit() {
        return rowSizeLimit;
    }

    public void setRowSizeLimit(Integer rowSizeLimit) {
        this.rowSizeLimit = rowSizeLimit;
    }

    public Integer getFetchSize() {
        return fetchSize;
    }

    public void setFetchSize(Integer fetchSize) {
        this.fetchSize = fetchSize;
    }

    public Map<String, String> getTableMap() {
        return tableMap;
    }

    public String getScanStrategy() {
        return scanStrategy;
    }

    public void setScanStrategy(String scanStrategy) {
        this.scanStrategy = scanStrategy;
    }

    public List<TableMetaData> buildTableMetaData(){
        return tableMap.entrySet().stream().map(e -> {
            ConnectInfo connectInfo = this.connectInfo;
            TableMetaData tableMetaData = this.metaDataExplorer
                    .setConnectInfo(connectInfo)
                    .build(e.getValue(), e.getKey());

            if (this.rowSizeLimit == -1) {
                tableMetaData.setRowSizeLimit(tableMetaData.getRowSize());
            } else {
                tableMetaData.setRowSizeLimit(Math.min(this.rowSizeLimit, tableMetaData.getRowSize()));
            }

            tableMetaData.setTaskCode(this.getTaskCode());
            return tableMetaData;
        }).collect(Collectors.toList());
    }

}
